package com.guldan.jaina.manager;

import com.alibaba.fastjson.JSON;
import com.guldan.core.constants.CommonConstant;
import com.guldan.core.exception.BusinessException;
import com.guldan.core.manager.BaseManager;
import com.guldan.core.redis.CacheService;
import com.guldan.core.search.Pagination;
import com.guldan.core.utils.DateUtil;
import com.guldan.core.utils.MD5Util;
import com.guldan.jaina.dto.gauthority.GAuthorityDTO;
import com.guldan.jaina.dto.organization.OrganizationDTO;
import com.guldan.jaina.dto.users.*;
import com.guldan.jaina.utils.UserDomainConvertUtils;
import com.guldan.mapper.db.entity.*;
import com.guldan.mapper.db.mapper.GRoleMapperExt;
import com.guldan.mapper.db.mapper.UserRoleMapperExt;
import com.guldan.mapper.db.mapper.UsersMapperExt;
import net.sf.json.JSONArray;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Silas.
 * Date: 2016/11/18
 * Time: 23:56
 */
@Service
public class UserManager extends BaseManager {

    @Autowired
    private CacheService cacheService;

    @Autowired
    private UsersMapperExt usersMapperExt;

    @Autowired
    private UserRoleMapperExt userRoleMapperExt;

    @Autowired
    private GAuthorityManager gAuthorityManager;

    @Autowired
    private AreaManager areaManager;

    @Autowired
    private OrganizationManager organizationManager;

    @Autowired
    private GRoleMapperExt gRoleMapperExt;

    //获取单个用户信息
    public UsersDTO get(Integer userId) {
        UsersDTO dto = UserDomainConvertUtils.convert(usersMapperExt.selectByPrimaryKey(userId));

        if (dto.getAreaId() != null && dto.getAreaId() > 0) {
            try {
                dto.setAreaName(areaManager.get(dto.getAreaId()).getAreaName());
            } catch (Exception ex) {


            }
        }
        if (StringUtils.isNotBlank(dto.getWorkOrg())) {
            try {
                dto.setWorkOrgName(organizationManager.getByOrgCode(dto.getWorkOrg()).getOrgName());
            } catch (Exception ex) {
                String s = ex.getMessage();
                logger.info(ex.getMessage());

            }
        }
        return dto;
    }

    //删除单个用户信息
    public Boolean delete(Integer userId) {
        Users entity = usersMapperExt.selectByPrimaryKey(userId);
        entity.setIsDelete(true);
        entity.setModifyTime(DateUtil.getCurrentTime());
        return usersMapperExt.updateByPrimaryKeySelective(entity) > 0;
    }

    //分页获取用户列表
    public Pagination<UsersDTO> list(UsersSearchDTO usersSearchDTO) {

        logger.info("usersSearchDTO：" + JSON.toJSONString(usersSearchDTO));

        Pagination<UsersDTO> result = new Pagination<UsersDTO>(usersSearchDTO.getCurrentPage(), usersSearchDTO.getPerPage());
        UsersExample example = buildSearchExample(usersSearchDTO);
        int total = usersMapperExt.countByExample(example);
        result.setTotalCount(total);
        if (total > 0) {
            List<UsersDTO> data = new ArrayList<UsersDTO>();
            List<Users> list = usersMapperExt.selectByExampleWithPaging(example, result.getOffset(), result.getPageSize());
            for (Users entity : list) {
                UsersDTO dto = UserDomainConvertUtils.convert(entity);
                if (dto.getAreaId() != null && dto.getAreaId() > 0) {
                    try {
                        dto.setAreaName(areaManager.get(dto.getAreaId()).getAreaName());
                    } catch (Exception ex) {
                    }
                }
                if (dto.getWorkOrg() != null && StringUtils.isNotBlank(dto.getWorkOrg())) {
                    try {
                        dto.setWorkOrgName(organizationManager.getByOrgCode(dto.getWorkOrg()).getOrgName());
                    } catch (Exception ex) {
                    }
                }
                data.add(dto);
            }
            result.setList(data);
        }
        return result;
    }

    //判断某个帐号是否已经存在
    private Boolean checkExist(String userAccount) {
        UsersExample example = new UsersExample();
        UsersExample.Criteria criteria = example.createCriteria();
        criteria.andUserAccountEqualTo(userAccount);
        criteria.andIsDeleteEqualTo(false);
        int count = usersMapperExt.countByExample(example);
        if (count > 0) {
            return true;
        } else {
            return false;
        }
    }

    //新增/更新单个用户，传入：UsersDTO
    public UsersDTO save(UsersDTO dto) throws BusinessException {

        Users entity;
        if (dto.getUserId() != null && dto.getUserId() > 0) {
            entity = usersMapperExt.selectByPrimaryKey(dto.getUserId());

            entity.setUserType(dto.getUserType());
            entity.setUserAccount(dto.getUserAccount());
            entity.setUserName(dto.getUserName());
            entity.setIdentityNumber(dto.getIdentityNumber());
            entity.setWorkOrg(dto.getWorkOrg());
            entity.setAreaId(dto.getAreaId());
            entity.setPhone(dto.getPhone());
            entity.setFaxNum(dto.getFaxNum());
            if (StringUtils.isNotBlank(dto.getPassword())) {
                entity.setPassword(MD5Util.MD5(dto.getPassword()));
            }
            entity.setRemark(dto.getRemark());
            entity.setLoginTypeCode(dto.getLoginTypeCode());
            entity.setDisabled(dto.getDisabled());
            entity.setModifyTime(DateUtil.getCurrentTime());
            entity.setModifier(dto.getModifier());
            usersMapperExt.updateByPrimaryKeySelective(entity);
        } else {

            //判断是否存存在
            if (checkExist(dto.getUserAccount())) {
                throw new BusinessException("该帐号已存在");
            }

            entity = new Users();

            entity.setUserType(dto.getUserType());
            entity.setUserAccount(dto.getUserAccount());
            entity.setUserName(dto.getUserName());
            entity.setIdentityNumber(dto.getIdentityNumber());
            entity.setWorkOrg(dto.getWorkOrg());
            entity.setAreaId(dto.getAreaId());
            entity.setPhone(dto.getPhone());
            entity.setFaxNum(dto.getFaxNum());
            entity.setPassword(MD5Util.MD5(dto.getPassword()));
            entity.setRemark(dto.getRemark());
            entity.setLoginTypeCode(dto.getLoginTypeCode());

            entity.setDisabled(dto.getDisabled());
            entity.setCreator(dto.getModifier());
            entity.setCreateTime(DateUtil.getCurrentTime());
            usersMapperExt.insertSelective(entity);
        }
        dto = get(entity.getUserId());
        return dto;
    }

    //获取某个用户的角色列表
    public List<UserRoleDTO> userRoleList(Integer userId) {
        UserRoleExample example = new UserRoleExample();
        UserRoleExample.Criteria criteria = example.createCriteria();
        criteria.andUserIdEqualTo(userId);
        criteria.andIsDeleteEqualTo(false);
        List<UserRole> entityList = userRoleMapperExt.selectByExample(example);
        List<UserRoleDTO> dtoList = new ArrayList<>();
        if (entityList != null && entityList.size() > 0) {
            for (UserRole entity : entityList) {
                dtoList.add(UserDomainConvertUtils.convert(entity));
            }
        }
        return dtoList;
    }

    //删除某个用户的角色，传入：userid，roleId
    public List<UserRoleDTO> userDeleteRole(Integer userId, Integer roleId) {
        UserRoleExample example = new UserRoleExample();
        UserRoleExample.Criteria criteria = example.createCriteria();
        criteria.andUserIdEqualTo(userId);
        criteria.andRoleIdEqualTo(roleId);
        userRoleMapperExt.deleteByExample(example);
        return userRoleList(userId);
    }

    //修改某个用户的角色列表
    public List<UserRoleDTO> userSaveRole(UserRoleSaveDTO userRoleSaveDTO) {
        List<UserRoleDTO> list = new ArrayList<>();
        if (userRoleSaveDTO != null && userRoleSaveDTO.getRoleIds() != null && userRoleSaveDTO.getRoleIds().size() > 0) {
            //先删除所有的记录，再进行添加
            UserRoleExample example = new UserRoleExample();
            UserRoleExample.Criteria criteria = example.createCriteria();
            criteria.andUserIdEqualTo(userRoleSaveDTO.getUserId());
            userRoleMapperExt.deleteByExample(example);

            //删除后进行逐个添加
            for (Integer roleId : userRoleSaveDTO.getRoleIds()) {
                UserRole userRole = new UserRole();
                userRole.setUserId(userRoleSaveDTO.getUserId());
                userRole.setRoleId(roleId);
                userRole.setDisabled(false);
                userRole.setIsDelete(false);
                userRole.setCreateTime(DateUtil.getCurrentTime());

                userRoleMapperExt.insertSelective(userRole);
            }
        }
        return userRoleList(userRoleSaveDTO.getUserId());
    }

    //修改密码接口
    public Boolean userUpdatePwd(UserPwdUpdateDTO dto) {
        Boolean ret = true;
        //先验证旧密码是否正确
        Users entity = usersMapperExt.selectByPrimaryKey(dto.getUserId());
        if (entity.getPassword().equals(MD5Util.MD5(dto.getOldPwd()))) {
            //如果旧密码正确，则继续
            //然后修改为新的密码
            entity.setPassword(MD5Util.MD5(dto.getNewPwd()));
            usersMapperExt.updateByPrimaryKeySelective(entity);
        } else {
            ret = false;
        }
        return ret;

    }

    //删除某个用户接口
    public Boolean userDelete(Integer userId) {
        Boolean ret = true;
        Users entity = usersMapperExt.selectByPrimaryKey(userId);
        entity.setIsDelete(true);
        entity.setModifyTime(DateUtil.getCurrentTime());
        ret = usersMapperExt.updateByPrimaryKeySelective(entity) > 0;
        return ret;
    }

    //build查询Example
    private UsersExample buildSearchExample(UsersSearchDTO search) {
        UsersExample example = new UsersExample();
        UsersExample.Criteria criteria = example.createCriteria();

        if (search.getUserId() != null && search.getUserId() > 0) {
            criteria.andUserIdEqualTo(search.getUserId());
        }
        if (StringUtils.isNotBlank(search.getUserType())) {
            criteria.andUserTypeEqualTo(search.getUserType());
        }

        if (search.getAreaId() != null && search.getAreaId() > 0) {
            List<Integer> ids = (List<Integer>) cacheService.getCache(String.format(CommonConstant.KEY_AREA, search.getAreaId()));

            if (ids != null && ids.size() > 0) {
                ids.add(search.getAreaId());
                criteria.andAreaIdIn(ids);
            } else {
                criteria.andAreaIdEqualTo(search.getAreaId());
            }

        }

        if (StringUtils.isNotBlank(search.getUserAccount())) {
            criteria.andUserAccountLike("%" + search.getUserAccount() + "%");
        }
        if (StringUtils.isNotBlank(search.getUserName())) {
            criteria.andUserNameLike("%" + search.getUserName() + "%");
        }
        if (StringUtils.isNotBlank(search.getWorkOrg())) {
            //criteria.andWorkOrgLike("%" + search.getWorkOrg() + "%");
            List<String> codes = (List<String>) cacheService.getCache(String.format(CommonConstant.KEY_ORG_CODE, search.getWorkOrg()));
            if (codes != null && codes.size() > 0) {
                codes.add(search.getWorkOrg());
                criteria.andWorkOrgIn(codes);
            } else {
                criteria.andWorkOrgEqualTo(search.getWorkOrg());
            }
        }
        if (search.getDisabled() != null) {
            criteria.andDisabledEqualTo(search.getDisabled());
        }
        criteria.andIsDeleteEqualTo(Boolean.FALSE);
        if (StringUtils.isNotBlank(search.getOrderByClause())) {
            example.setOrderByClause(search.getOrderByClause());
        } else {
            example.setOrderByClause("user_id asc");
        }
        return example;
    }


    //用户登录接口
    public UsersDTO login(String userAccount, String password, String JSESSIONID) {
        UsersDTO dto = null;


        if (StringUtils.isBlank(userAccount) || StringUtils.isBlank(password)) return dto;


        UsersExample example = new UsersExample();
        UsersExample.Criteria criteria = example.createCriteria();
        criteria.andUserAccountEqualTo(userAccount);
        criteria.andDisabledEqualTo(false);
        criteria.andIsDeleteEqualTo(false);
        List<Users> entityList = usersMapperExt.selectByExample(example);
        if (entityList != null && entityList.size() > 0) {
            //存在该用户
            Users entity = entityList.get(0);
            //验证用户名和密码是否一致
            if (entity.getPassword().equals(MD5Util.MD5(password))) {
                //如果密码正确，则继续，修改最后登录时间
                entity.setLastLoginTime(DateUtil.getCurrentTime());

                usersMapperExt.updateByPrimaryKeySelective(entity);

                dto = UserDomainConvertUtils.convert(entity);

                if (dto.getAreaId() != null && dto.getAreaId() > 0) {
                    try {
                        dto.setAreaName(areaManager.get(dto.getAreaId()).getAreaName());
                    } catch (Exception ex) {
                    }
                }

                //获取用户角色code
                List<UserRoleDTO> userRoleDTOs = userRoleList(dto.getUserId());
                if (userRoleDTOs != null && userRoleDTOs.size() > 0) {
                    dto.setUserRole(gRoleMapperExt.selectByPrimaryKey(userRoleDTOs.get(0).getRoleId()).getRoleCode());
                }

                if (dto.getWorkOrg() != null && StringUtils.isNotBlank(dto.getWorkOrg())) {
                    try {

                        OrganizationDTO o = organizationManager.getByOrgCode(dto.getWorkOrg());
                        dto.setAreaId(o.getAreaId());
                        dto.setAreaName(areaManager.get(o.getAreaId()).getAreaName());
                        dto.setWorkOrgName(o.getOrgName());
                    } catch (Exception ex) {
                    }
                }

                //登录成功，将用户信息实体写入redis缓存
                UserCacheDTO userCacheDTO = new UserCacheDTO();
                userCacheDTO.setUserId(entity.getUserId());
                userCacheDTO.setJSESSIONID(JSESSIONID);
                userCacheDTO.setUser(dto);
                userCacheDTO.setMenu(getMenuByUserId(entity.getUserId()));
                logger.info("json4:JSESSIONID_" + JSESSIONID);
                logger.info("json4:" + JSONArray.fromObject(userCacheDTO).toString());

//                cacheService.putCache("JSESSIONID_MENU_" + JSESSIONID, userCacheDTO.getMenu(), 60);

                cacheService.putCache("JSESSIONID_" + JSESSIONID, userCacheDTO, 60);//过期时间设置为1分钟
            }
        }

        return dto;
    }

    //将客户端JSESSIONID注册到redis
    public UserCacheDTO registClient(String token, String JSESSIONID) {
        UserCacheDTO userCacheDTO = getUserCache(token);
        if (userCacheDTO != null) {
            //token校验通过
            //注册JSESSIONID
            cacheService.putCache("JSESSIONID_" + JSESSIONID, userCacheDTO, 60 * 4 * 60);//过期时间设置为30分钟
        }
        return userCacheDTO;
    }

    //通过用户id获取用户所授权树形菜单
    public List<GAuthorityDTO> getMenuByUserId(Integer userId) {

        List<GAuthorityDTO> list = null;
        //首选获取该用户的角色信息
        List<UserRoleDTO> userRoleDTOList = userRoleList(userId);
        if (userRoleDTOList != null && userRoleDTOList.size() > 0) {
            UserRoleDTO userRoleDTO = userRoleDTOList.get(0);
            list = gAuthorityManager.getAuthorityListByRoleId(userRoleDTO.getRoleId());

            logger.info("json3:" + JSONArray.fromObject(list).toString());

        }

        return list;
    }

    //通过登录用户JSESSIONID获取用户所授权树形菜单
    public List<GAuthorityDTO> getMenuByJSESSIONID(String JSESSIONID) {
        List<GAuthorityDTO> list = null;
        Object o = cacheService.getCache("JSESSIONID_" + JSESSIONID);
        if (o != null) {
            //用户已经成功登录
            UserCacheDTO userCacheDTO = (UserCacheDTO) o;
            list = userCacheDTO.getMenu();
        }
        return list;
    }

    //判断某个JSESSIONID是否已经登录
    public UserCacheDTO authentication(String JSESSIONID) {
        Object object = cacheService.getCache("JSESSIONID_" + JSESSIONID);
        if (object != null) {
            return (UserCacheDTO) object;
        } else {
            return null;
        }

    }

    //获取某个用户的登录缓存实体
    public UserCacheDTO getUserCache(String JSESSIONID) {
        UserCacheDTO userCacheDTO = (UserCacheDTO) cacheService.getCache("JSESSIONID_" + JSESSIONID);
//        userCacheDTO.setMenu((List<GAuthorityDTO>) cacheService.getCache("JSESSIONID_MENU_" + JSESSIONID));
        logger.info("json7:JSESSIONID_" + JSESSIONID);
        logger.info("json7:" + JSONArray.fromObject(userCacheDTO).toString());
        return userCacheDTO;
    }


    //退出登录
    public Boolean loginOut(String JSESSIONID) {
        Object object = cacheService.getCache("JSESSIONID_" + JSESSIONID);
        if (object != null) {
            cacheService.removeCache("JSESSIONID_" + JSESSIONID);
        }
        return true;

    }
}
